package com.tct.worktimeboard.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tct.worktimeboard.config.DataSourceContextHolder;
import com.tct.worktimeboard.entity.*;
import com.tct.worktimeboard.entity.excel.CountMarkUserWork;
import com.tct.worktimeboard.entity.excel.CountUserWork;
import com.tct.worktimeboard.entity.excel.WorkExcelTemplate;
import com.tct.worktimeboard.entity.vo.DepartmentVO;
import com.tct.worktimeboard.feishu.SendMessage;
import com.tct.worktimeboard.mapper.ProjectMapper;
import com.tct.worktimeboard.mapper.UserInfoMapper;
import com.tct.worktimeboard.mapper.WorkMapper;
import com.tct.worktimeboard.service.IGroupTypeService;
import com.tct.worktimeboard.service.IWorkService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tct.worktimeboard.util.JsonUtil;
import com.tct.worktimeboard.util.PageUtil;
import com.tct.worktimeboard.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author liyongkui
 * @since 2021-02-22
 */
@Slf4j
@Service
public class WorkServiceImpl extends ServiceImpl<WorkMapper, Work> implements IWorkService {

    @Resource
    WorkMapper workMapper;
    @Resource
    ProjectMapper projectMapper;
    @Resource
    UserInfoMapper userInfoMapper;
    @Autowired
    IGroupTypeService groupTypeService;
    @Autowired
    SendMessage sendMessage;

    @Override
    public JSONObject getWork(Work work) {
        int pageNum = 1;
        int pageSize = 10;
        if(work.getPageNum() != null && work.getPageSize() != null) {
            pageNum = work.getPageNum();
            pageSize = work.getPageSize();
        }
        Page<LinkedHashMap<String,Object>> page = new Page<>(pageNum,pageSize);
        Page<LinkedHashMap<String, Object>> result = workMapper.getWork(page, work);
        return JsonUtil.toJsonData(result);
    }

    @Override
    public JSONObject addWork(Work work) {
        work.setCreateTime(TimeUtil.getDateTime());
        workMapper.insert(work);
//        sendMessage.sendMakeWorkTimeMessage(work);
        return JsonUtil.toJsonData();
    }

    @Override
    public JSONObject updateWork(Work work) {
        if(work.getMakeStatus()==null) {work.setCreateTime(TimeUtil.getDateTime());}
//        work.setMakeStatus(null);
        workMapper.updateWork(work);
//        sendMessage.sendMakeWorkTimeMessage(work);
        return JsonUtil.toJsonData();
    }

    @Override
    public JSONObject deleteWork(List<Integer> idList) {
        workMapper.deleteBatchIds(idList);
        return JsonUtil.toJsonData();
    }

    @Override
    public JSONObject listPageByMakeUserIdAndMakeStatus(Work work) {
        if(work.isPaged()){
            PageHelper.startPage(work.getPageNum(),work.getPageSize());
        }
        QueryWrapper<Work> query = new QueryWrapper<>();
        query.eq("make_user_id",work.getMakeUserId());
        if(work.getQueryEndTime() != null && !work.getQueryEndTime().isEmpty()){
            query.le("work_start_time",work.getQueryEndTime());
        }
        if(work.getQueryStartTime() != null && !work.getQueryStartTime().isEmpty()){
            query.ge("work_end_time",work.getQueryStartTime());
        }
        if(work.getProjectId()!=null){
            query.eq("project_id",work.getProjectId());
        }
        if(work.getGroupTypeId()!=null){
            query.eq("group_type_id",work.getGroupTypeId());
        }
        if(work.getUsername()!=null&&!work.getUsername().isEmpty()){
            query.like("username",work.getUsername());
        }
        if(work.getMakeStatus() == null){
            query.isNull("make_status");
        }else{
            query.eq("make_status",work.getMakeStatus());
        }

        List<Work> list = this.list(query);
        for(Work w : list){
            w.setProjectName(getProjectNameById(w.getProjectId()));
        }
        PageInfo<Work> info = new PageInfo<>(list);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total",info.getTotal());
        jsonObject.put("rows",info.getList());
        return JsonUtil.toJsonMessage(jsonObject);
    }

    private String getProjectNameById(Integer id){
        Project project = projectMapper.selectById(id);
        if(project==null){
            return "";
        }
        return project.getProjectName();
    }

    @Override
    public void listPageByMakeUserIdAndMakeStatusDownloadExcel(HttpServletResponse response, Work work) throws Exception {
        if(work.isPaged()){
            PageHelper.startPage(work.getPageNum(),work.getPageSize());
        }
        QueryWrapper<Work> query = new QueryWrapper<>();
        query.eq("make_user_id",work.getMakeUserId());
        if(work.getQueryEndTime() != null && !work.getQueryEndTime().isEmpty()){
            query.le("work_start_time",work.getQueryEndTime());
        }
        if(work.getQueryStartTime() != null && !work.getQueryStartTime().isEmpty()){
            query.ge("work_end_time",work.getQueryStartTime());
        }
        if(work.getProjectId()!=null){
            query.eq("project_id",work.getProjectId());
        }
        if(work.getGroupTypeId()!=null){
            query.eq("group_type_id",work.getGroupTypeId());
        }
        if(work.getUsername()!=null&&!work.getUsername().isEmpty()){
            query.like("username",work.getUsername());
        }
        if(work.getMakeStatus() == null){
            query.isNull("make_status");
        }else{
            query.eq("make_status",work.getMakeStatus());
        }

        List<Work> list = this.list(query);
        for(Work w : list){
            w.setProjectName(getProjectNameById(w.getProjectId()));
            w.setGroupTypeName(getGroupTypeNameById(w.getGroupTypeId()));
        }

        List<WorkExcelTemplate> workExcelTemplateList = new ArrayList<>();
        list.forEach(w ->{
            WorkExcelTemplate workExcelTemplate = new WorkExcelTemplate();
            BeanUtils.copyProperties(w,workExcelTemplate);
            workExcelTemplateList.add(workExcelTemplate);
        });
        PageInfo<WorkExcelTemplate> info = new PageInfo<>(workExcelTemplateList);
        log.info("导出的excel数：{}",JSONObject.toJSONString(info.getList()));
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("工时统计","审批人工时统计详情", ExcelType.XSSF),
                WorkExcelTemplate.class, info.getList());
        String fileName = "审批人工时统计详情";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.addHeader("Content-Disposition","attachment; filename=" + new String(fileName.getBytes("GBK"),"ISO8859_1") + ".xlsx");
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
    }

    private String getGroupTypeNameById(Integer id){
        GroupType groupTpe = groupTypeService.getById(id);
        if(groupTpe==null){
            return "";
        }
        return groupTpe.getKindName();
    }

    @Override
    public JSONObject listPageByUserIdAndMakeStatus(Work work) {
        if(work.isPaged()){
            PageHelper.startPage(work.getPageNum(),work.getPageSize());
        }
        QueryWrapper<Work> query = new QueryWrapper<>();
        query.eq("user_id",work.getUserId());
        if(work.getQueryEndTime() != null && !work.getQueryEndTime().isEmpty()){
            query.le("work_start_time",work.getQueryEndTime());
        }
        if(work.getQueryStartTime() != null && !work.getQueryStartTime().isEmpty()){
            query.ge("work_end_time",work.getQueryStartTime());
        }
        if(work.getMakeStatus() == null){
            query.isNull("make_status");
        }else{
            query.eq("make_status",work.getMakeStatus());
        }
        List<Work> list = this.list(query);
        list.forEach(item->{
            item.setProjectName(getProjectNameById(item.getProjectId()));
        });
        PageInfo<Work> info = new PageInfo<>(list);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total",info.getTotal());
        jsonObject.put("rows",info.getList());
        return JsonUtil.toJsonMessage(jsonObject);
    }

    @Override
    public void listPageByUserIdAndMakeStatusDownloadExcel(HttpServletResponse response, Work work) throws Exception{
        if(work.isPaged()){
            PageHelper.startPage(work.getPageNum(),work.getPageSize());
        }
        QueryWrapper<Work> query = new QueryWrapper<>();
        query.eq("user_id",work.getUserId());
        if(work.getQueryEndTime() != null && !work.getQueryEndTime().isEmpty()){
            query.le("work_start_time",work.getQueryEndTime());
        }
        if(work.getQueryStartTime() != null && !work.getQueryStartTime().isEmpty()){
            query.ge("work_end_time",work.getQueryStartTime());
        }
        if(work.getMakeStatus() == null){
            query.isNull("make_status");
        }else{
            query.eq("make_status",work.getMakeStatus());
        }
        List<Work> list = this.list(query);
        List<WorkExcelTemplate> workExcelTemplateList = new ArrayList<>();
        list.forEach(w ->{
            WorkExcelTemplate workExcelTemplate = new WorkExcelTemplate();
            BeanUtils.copyProperties(w,workExcelTemplate);
            workExcelTemplateList.add(workExcelTemplate);
        });
        PageInfo<WorkExcelTemplate> info = new PageInfo<>(workExcelTemplateList);

        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("工时统计","申报人工时统计详情", ExcelType.XSSF),
                WorkExcelTemplate.class, info.getList());
        String fileName = "申报人工时统计详情";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.addHeader("Content-Disposition","attachment; filename=" + new String(fileName.getBytes("GBK"),"ISO8859_1") + ".xlsx");
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
    }


    @Override
    public PageInfo<Project> countByProjectAndUserId(Project project) {
//        PageUtil.makePage(project);
        List<Project> count = workMapper.countByProjectAndUserId(project);
        DataSourceContextHolder.setContextHolder("db2");    //切换到数据源2
        count.forEach(p->{
            List<DepartmentVO> tempList = new ArrayList<>();
            List<DepartmentVO> departmentVOList = new ArrayList<>();
            p.getWorkList().forEach(item->{
                DepartmentVO departmentVO = DepartmentVO.builder().departmentName(getDepartmentByUserId(item.getUserId())).totalTime(item.getWorkTime()).build();
                tempList.add(departmentVO);
            });
            Map<String, List<DepartmentVO>> collect = tempList.stream().collect(Collectors.groupingBy(DepartmentVO::getDepartmentName));
            for (String key : collect.keySet()) {
                List<DepartmentVO> values = collect.get(key);
                BigDecimal bigDecimal = null;
                for (DepartmentVO vo : values) {
                    if (bigDecimal == null) {
                        bigDecimal = vo.getTotalTime();
                    } else {
                        bigDecimal = bigDecimal.add(vo.getTotalTime());
                    }
                }
                DepartmentVO departmentVO = DepartmentVO.builder().departmentName(key).totalTime(bigDecimal).build();
                departmentVOList.add(departmentVO);
            }
            p.setDepartmentVOList(departmentVOList);
        });
        DataSourceContextHolder.clear();    //使用完清理数据源设置
        return new PageInfo<>(count);
    }

    @Override
    public void countGroupByProjectAndUserIdDownloadExcel(HttpServletResponse response,Project project) throws Exception {
        List<Project> projects = countByProjectAndUserId(project).getList();
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("工时统计","项目工时统计", ExcelType.XSSF),
                Project.class, projects);
        String fileName = "分项目工时统计";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.addHeader("Content-Disposition","attachment; filename=" + new String(fileName.getBytes("GBK"),"ISO8859_1") + ".xlsx");
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
    }

    /**
     * 根据用户id获取部门
     * @param userId 用户ID
     * @return 返回部门名称
     */
    public String getDepartmentByUserId(Integer userId){
        return userInfoMapper.selectById(userId).getDepartment();
    }

    @Override
    public JSONObject countGroupByGroupType(Long groupTypeId) {
        List<GroupType> groupTypes = workMapper.countGroupByGroupType(groupTypeId);
        return JsonUtil.toJsonData(groupTypes);
    }

    @Override
    public void countGroupByGroupTypeDownloadExcel(HttpServletResponse response,Long groupTypeId) throws Exception{
        List<GroupType> groupTypes = workMapper.countGroupByGroupType(groupTypeId);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("工时统计","部门工时统计", ExcelType.XSSF),
                GroupType.class, groupTypes);
        String fileName = "分部门工时统计";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.addHeader("Content-Disposition","attachment; filename=" + new String(fileName.getBytes("GBK"),"ISO8859_1") + ".xlsx");
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
    }


    @Override
    public JSONObject countGroupByUserId(Work work) {
        PageUtil.makePage(work);
        List<Work> works = workMapper.countGroupByUserId(work);
        return JsonUtil.toJsonData(new PageInfo<>(works));
    }

    @Override
    public void countGroupByUserIdDownloadExcel(HttpServletResponse response, Work work) throws Exception {
        List<Work> works = workMapper.countGroupByUserId(work);
        List<CountUserWork> countUserWorks = new ArrayList<>();
        works.forEach(w -> {
            CountUserWork countUserWork = new CountUserWork();
            BeanUtils.copyProperties(w,countUserWork);
            countUserWorks.add(countUserWork);
        });
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("工时统计","负责人工时统计", ExcelType.XSSF),
                CountUserWork.class, countUserWorks);
        String fileName = "负责人工时统计";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.addHeader("Content-Disposition","attachment; filename=" + new String(fileName.getBytes("GBK"),"ISO8859_1") + ".xlsx");
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
    }

    @Override
    public JSONObject countGroupByMakeUserId(Work work) {
        PageUtil.makePage(work);
        List<Work> works = workMapper.countGroupByMakeUserId(work);
        return JsonUtil.toJsonData(new PageInfo<>(works));
    }

    @Override
    public void countGroupByMakeUserIdDownloadExcel(HttpServletResponse response, Work work) throws Exception {
        List<Work> works = workMapper.countGroupByMakeUserId(work);
        List<CountMarkUserWork> countUserWorks = new ArrayList<>();
        works.forEach(w -> {
            CountMarkUserWork countUserWork = new CountMarkUserWork();
            BeanUtils.copyProperties(w,countUserWork);
            countUserWorks.add(countUserWork);
        });
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("工时统计","审批人工时统计", ExcelType.XSSF),
                CountMarkUserWork.class, countUserWorks);
        String fileName = "审批人工时统计";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.addHeader("Content-Disposition","attachment; filename=" + new String(fileName.getBytes("GBK"),"ISO8859_1") + ".xlsx");
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
    }

    @Override
    public JSONObject countGroupByWorkKindId(String workName) {
        List<WorkKind> workKinds = workMapper.countGroupByWorkKindId(workName);
        return JsonUtil.toJsonData(workKinds);
    }

    @Override
    public void countGroupByWorkKindIdDownloadExcel(HttpServletResponse response, String workName) throws Exception {
        List<WorkKind> workKinds = workMapper.countGroupByWorkKindId(workName);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("工时统计","任务类型工时统计", ExcelType.XSSF),
                WorkKind.class, workKinds);
        String fileName = "任务类型工时统计";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.addHeader("Content-Disposition","attachment; filename=" + new String(fileName.getBytes("GBK"),"ISO8859_1") + ".xlsx");
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
    }

    @Override
    public JSONObject countGroupByWorkTask(WorkTask workTask) {
        if (workTask.isPaged()) {
            PageHelper.startPage(workTask.getPageNum(),workTask.getPageSize());
        }
        List<WorkTask> workTasks = workMapper.countGroupByWorkTask(workTask);
        PageInfo<WorkTask> info = new PageInfo<>(workTasks);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total",info.getTotal());
        jsonObject.put("rows",info.getList());
        return JsonUtil.toJsonMessage(jsonObject);
    }

    @Override
    public JSONObject listPageByCondition(Work work) {
        if(work.isPaged()){
            PageHelper.startPage(work.getPageNum(),work.getPageSize());
        }
        QueryWrapper<Work> query = new QueryWrapper<>();
        if(StringUtils.isNotBlank(work.getQueryEndTime())){
            query.le("work_start_time",work.getQueryEndTime());
        }
        if(StringUtils.isNotBlank(work.getQueryStartTime())){
            query.ge("work_end_time",work.getQueryStartTime());
        }
        if(work.getTaskId() != null){
            query.eq("task_id",work.getTaskId());
        }
        if(work.getMakeStatus() == null){
            query.isNull("make_status");
        }else{
            query.eq("make_status",work.getMakeStatus());
        }
        List<Work> list = this.list(query);
        PageInfo<Work> info = new PageInfo<>(list);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total",info.getTotal());
        jsonObject.put("rows",info.getList());
        return JsonUtil.toJsonMessage(jsonObject);
    }
}
